<template>
  <div>
    <!-- 查询表单 -->
    <el-form :inline="true" :model="query" class="demo-form-inline">
      <el-form-item>
        <el-input v-model="query.operator" placeholder="按患者姓名查询"></el-input>
      </el-form-item>
      <el-form-item>
        <el-date-picker
            v-model="query.operateDate"
            align="right"
            type="date"
            placeholder="按日期查询"
            :picker-options="pickerOptions"
        ></el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="fetchRecords">查询</el-button>
      </el-form-item>
    </el-form>

    <!-- 表格展示 -->
    <el-table :data="paginatedData" stripe style="width: 95vw; margin: 0 auto; border-radius: 20px; border: 1px skyblue solid;">
      <el-table-column prop="id" label="ID"></el-table-column>
      <el-table-column prop="operator" label="患者姓名"></el-table-column>
      <el-table-column prop="url" label="图片"></el-table-column>
      <el-table-column prop="operateDate" label="查询日期"></el-table-column>
      <el-table-column prop="region" label="地区"></el-table-column>
      <el-table-column prop="result" label="结论"></el-table-column>
    </el-table>

    <!-- 分页 -->
    <el-pagination
        style="margin: 20px auto;"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
    ></el-pagination>

    <!-- 地区统计与排行榜 -->
    <div style="display: flex; justify-content: center; gap: 20px; margin-top: 20px;">
      <!-- 地区统计 -->
      <el-card shadow="hover" style="width: 500px;">
        <div class="card-header">
          <p class="card-header-title">地区统计</p>
          <p class="card-header-desc">最近一个月的病例统计</p>
        </div>
        <v-chart class="map-chart" :option="mapOptions" />
      </el-card>

      <!-- 排行榜 -->
      <el-card shadow="hover" style="width: 500px;">
        <div class="card-header">
          <p class="card-header-title">排行榜</p>
          <p class="card-header-desc">来自各个地区的患者统计</p>
        </div>
        <div v-if="ranks.length > 0">
          <div class="rank-item" v-for="(rank, index) in ranks" :key="index">
            <div class="rank-item-avatar">{{ index + 1 }}</div>
            <div class="rank-item-content">
              <div class="rank-item-top">
                <div class="rank-item-title">{{ rank.region }}</div>
                <div class="rank-item-desc">病例：{{ rank.count }}</div>
              </div>
              <el-progress
                  :show-text="false"
                  striped
                  :stroke-width="10"
                  :percentage="rank.percent"
                  :color="rank.color"
              />
            </div>
          </div>
        </div>
        <div v-else>
          <p style="text-align: center">加载中...</p>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script setup lang="ts">
import VChart from 'vue-echarts';
import {onMounted, reactive, ref} from 'vue';
import axios from 'axios';
import {registerMap, use} from "echarts/core";
import {CanvasRenderer} from "echarts/renderers";
import {BarChart, LineChart, MapChart, PieChart} from 'echarts/charts';
import {
  GridComponent,
  LegendComponent,
  TitleComponent,
  TooltipComponent,
  VisualMapComponent,
} from 'echarts/components';
import chinaMap from "@/utils/china";
import {useRouter} from 'vue-router';

const router = useRouter();

use([CanvasRenderer, MapChart]);
registerMap("china", chinaMap);
use([
  CanvasRenderer,
  BarChart,
  GridComponent,
  LineChart,
  PieChart,
  TooltipComponent,
  LegendComponent,
  TitleComponent,
  VisualMapComponent,
  MapChart,
]);
registerMap('china', chinaMap);

// 数据状态
const records = ref<any[]>([]);
const paginatedData = ref<any[]>([]);
const total = ref(0);
const currentPage = ref(1);
const pageSize = ref(10);
const query = reactive({
  operator: "",
  operateDate: null as Date | null,
});

// 排行模块的数据
const ranks = ref<any[]>([]);

// 地图选项
const mapOptions = ref({
  title: {
    text: '地区统计',
    left: 'center',
  },
  tooltip: {
    trigger: 'item',
  },
  visualMap: {
    min: 0,
    max: 1000,
    left: 'left',
    top: 'bottom',
    text: ['高', '低'],
    calculable: true,
  },
  series: [
    {
      name: '病例数',
      type: 'map',
      mapType: 'china',
      roam: true,
      label: {
        show: false, // 去掉地图上的字
      },
      data: [], // 初始数据为空
    },
  ],
});

// 日期选择器
const pickerOptions = ref<any>({
  shortcuts: [
    {
      text: '今天',
      onClick: (picker: any) => picker.$emit('pick', new Date()),
    },
    {
      text: '昨天',
      onClick: (picker: any) => {
        const date = new Date();
        date.setTime(date.getTime() - 3600 * 1000 * 24);
        picker.$emit('pick', date);
      },
    },
    {
      text: '一周前',
      onClick: (picker: any) => {
        const date = new Date();
        date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
        picker.$emit('pick', date);
      },
    },
  ],
});

// 格式化日期
const formatDate = (date: Date): string => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
};

// 创建 axios 实例
const instance = axios.create({
  baseURL: 'http://localhost:8080',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

// 请求拦截器
instance.interceptors.request.use(
    (config) => {
      // 从 localStorage 中获取 token
      const token = localStorage.getItem('token');
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    },
    (error) => {
      return Promise.reject(error);
    }
);

// 响应拦截器
instance.interceptors.response.use(
    (response) => {
      return response;
    },
    (error) => {
      return Promise.reject(error);
    }
);

// 查询分页处理
const fetchRecords = async () => {
  try {
    // 检查 query.operateDate 是否为有效的 Date 对象
    let formattedDate = null;
    if (query.operateDate instanceof Date && !isNaN(query.operateDate.getTime())) {
      formattedDate = formatDate(query.operateDate);
    }

    const params: QueryParams = {
      operator: query.operator,
    };

    // 如果 formattedDate 不为空，则添加到查询参数中
    if (formattedDate) {
      params.operateDate = formattedDate;
    }

    const response = await instance.get('/api/history', {
      params: params
    });

    // 检查 response.data 和 response.data.data 是否存在
    if (response && response.data) {
      if (response.data.code === 0 && response.data.msg === 'NOT_LOGIN') {
        console.error('用户未登录');
        // 跳转到登录页面
        router.push('/login');
        return;
      }

      if (Array.isArray(response.data.data)) {
        records.value = response.data.data;
        total.value = records.value.length;
        paginatedData.value = records.value.slice(
            (currentPage.value - 1) * pageSize.value,
            currentPage.value * pageSize.value
        );
        updateMapAndRanks(); // 更新地图和排行榜数据
        fetchMapData(); // 更新地图数据
      } else {
        console.error('返回的数据格式不正确:', response.data);
        records.value = [];
        total.value = 0;
        paginatedData.value = [];
      }
    } else {
      console.error('返回的数据格式不正确:', response.data);
      records.value = [];
      total.value = 0;
      paginatedData.value = [];
    }

    console.log('数据提交成功', response);
  } catch (error) {
    console.error('数据提交失败', error);
    console.error('日期', query.operateDate);
  }
};

// 更新地图与排行榜数据
const updateMapAndRanks = () => {
  const regionCounts = records.value.reduce((acc: any, record: any) => {
    acc[record.region] = (acc[record.region] || 0) + 1;
    return acc;
  }, {});
  // 更新排行榜数据
  const totalCases = records.value.length;
  ranks.value = Object.entries(regionCounts)
      .map(([region, count]: [string, number]) => ({
        region,
        count,
        percent: ((count / totalCases) * 100).toFixed(2),
        color: getRandomColor(), // 随机颜色
      }))
      .sort((a, b) => b.count - a.count);
};

const fetchMapData = async () => {
  try {
    console.log('Fetching map data...');
    const response = await instance.get('/api/history', {
      params: {
        operator: query.operator,
        operateDate: query.operateDate ? formatDate(query.operateDate) : null
      }
    });
    if (response.data.code === 1 && response.data.data) {
      // 统计每个地区的病例数
      const regionCounts = response.data.data.reduce((acc: Record<string, number>, record) => {
        acc[record.region] = (acc[record.region] || 0) + 1;
        return acc;
      }, {});
      // 更新地图数据
      mapOptions.value.series[0].data = Object.entries(regionCounts).map(([name, value]) => ({
        name,
        value,
      }));
    } else {
      console.warn('Unexpected response:', response);
    }
  } catch (error) {
    console.error('Failed to fetch map data:', error);
  }
};

// 分页大小与页码更改
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  fetchRecords();
};

const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  fetchRecords();
};

onMounted(() => {
  fetchRecords();
  fetchMapData();
});

// 生成随机颜色
const getRandomColor = () => {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
};
</script>


<style scoped>

.card-header {
  padding-left: 10px;
  margin-bottom: 20px;
}

.card-header-title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 5px;
}

.card-header-desc {
  font-size: 14px;
  color: #999;
}

.rank-item {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.rank-item-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #f2f2f2;
  text-align: center;
  line-height: 40px;
  margin-right: 10px;
}

.rank-item-content {
  flex: 1;
}

.rank-item-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #343434;
  margin-bottom: 10px;
}

.rank-item-desc {
  font-size: 14px;
  color: #999;
}
.map-chart {
  width: 100%;
  height: 350px;
}
.demo-form-inline{
  text-align: center;
}
:deep .cell{
  text-align: center;
}
.item{
  width: 20%;
}
:deep .el-table__row{
  height: 60px;
}
.top-input{
  height: 60px;
  font-size: 20px;
}
</style>
